﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FCMGAAI
{
    public class Validasi
    {
        public double[,] FUc1;
        public double FUc2;
        public double[,] HUc1;
        public double HUc2;
        public double SUc;
        double jarakSampelDenganPrototype;
        double jarakMinimumAntarPrototype;

        int jumlahBaris;
        int jumlahCluster;
        int jumlahKolom; 
        public double [,] matrikU;
        public double[,] pusatCluster;
        public double[,] dataInput;

        public Validasi(FCM1 Fcm)
        {
            jumlahBaris = Fcm.panjangBarisData;
            jumlahCluster = Fcm.JumlahCluster;
            jumlahKolom = Fcm.panjangKolomParameterData;
            dataInput = new double[Fcm.MDataAsli.GetLength(0), Fcm.MDataAsli.GetLength(1)];
            for (int i = 0; i < Fcm.MDataAsli.GetLength(0); i++)
                for (int j = 0; j < Fcm.MDataAsli.GetLength(1); j++)
                {
                    dataInput[i, j] = Fcm.MDataAsli[i, j];
                }
        }

        public void FillMatriks(int Validasi_mode)
        {
            matrikU = new double[ShareVariable.MatriksUdariFCM.GetLength(0), ShareVariable.MatriksUdariFCM.GetLength(1)];
            pusatCluster = new double[ShareVariable.MatriksPusatClusterFCM.GetLength(0), ShareVariable.MatriksPusatClusterFCM.GetLength(1)];
            if (Validasi_mode == 0)
            {
                for (int i= 0 ; i< matrikU.GetLength(0); i++)
                    for (int j = 0; j < matrikU.GetLength(1); j++)
                    {
                        matrikU[i, j] = ShareVariable.MatriksUdariFCM[i, j];
                    }
                for (int i = 0; i < pusatCluster.GetLength(0); i++)
                    for (int j = 0; j < pusatCluster.GetLength(1); j++)
                    {
                        pusatCluster[i, j] = ShareVariable.MatriksPusatClusterFCM[i, j];
                    }

            }
            else if (Validasi_mode == 1)
            {
                for (int i = 0; i < matrikU.GetLength(0); i++)
                    for (int j = 0; j < matrikU.GetLength(1); j++)
                    {
                        matrikU[i, j] = ShareVariable.MatriksUdariFCMGA[i, j];
                    }
                for (int i = 0; i < pusatCluster.GetLength(0); i++)
                    for (int j = 0; j < pusatCluster.GetLength(1); j++)
                    {
                        pusatCluster[i, j] = ShareVariable.MatriksPusatClusterFCMGA[i, j];
                    }
            }
        }


        public void koefisienPartisi()
        {
            FUc1 = new double[jumlahBaris, jumlahCluster];
            FUc2 = 0;
            for (int k = 0; k < jumlahCluster; k++)
            {
                for (int i = 0; i < jumlahBaris; i++)
                {
                    FUc1[i, k] += (Math.Pow(matrikU[i, k], 2));
                    FUc2 = FUc1[i, k] / jumlahBaris;
                    FUc2 = Math.Round(FUc2, 7);
                }
            }
            Console.WriteLine("fuc : " + FUc2);
        }

        public void entropyPartisi()
        {
            HUc1 = new double[jumlahBaris, jumlahCluster];
            HUc2 = 0;
            for (int k = 0; k < jumlahCluster; k++)
            {
                for (int i = 0; i < jumlahBaris; i++)
                {
                    HUc1[i, k] += matrikU[i, k] * Math.Log10(matrikU[i, k]);
                    HUc2 = (-1) * HUc1[i, k] / jumlahBaris;
                    HUc2 = Math.Round(HUc2, 7);
                }
            }
            Console.WriteLine("huc : " + HUc2);
        }

        public void fungsiValiditasKekompakanDanSeparasi()
        {
            double[,] jarak = new double[jumlahBaris, jumlahCluster];
            double[,] jarak2 = new double[jumlahBaris, jumlahCluster];
            double[,] jarak3 = new double[jumlahCluster, jumlahCluster];
            double[] jarak3Total = new double[jumlahCluster];
            SUc = 0;
            for (int k = 0; k < jumlahCluster; k++)
            {
                for (int i = 0; i < jumlahBaris; i++)
                {
                    for (int j = 0; j < jumlahKolom - 1; j++)
                    {
                        jarak[i, k] += Math.Pow((dataInput[i, j] - pusatCluster[k, j]), 2);
                        jarak2[i, k] += (Math.Sqrt(jarak[i, k])) * (Math.Pow(matrikU[i, k], 2));
                        jarakSampelDenganPrototype = jarak2[i, k];
                    }
                }
            }

            for (int k1 = 0; k1 < jumlahCluster; k1++)
            {
                for (int k2 = k1 + 1; k2 < jumlahCluster; k2++)
                {
                    for (int j = 0; j < jumlahKolom - 1; j++)
                    {
                        jarak3[k1, k2] += Math.Pow((pusatCluster[k1, j] - pusatCluster[k2, j]), 2);
                        jarak3Total[k1] = Math.Sqrt(jarak3[k1, k2]);

                        jarakMinimumAntarPrototype = jarak3Total[k1];
                        if (jarak3Total[k1] < jarakMinimumAntarPrototype && jarakMinimumAntarPrototype != 0)
                        {
                            jarakMinimumAntarPrototype = jarak3Total[k1];
                        }
                    }
                }
            }

            SUc = (jarakSampelDenganPrototype / jumlahBaris) / jarakMinimumAntarPrototype;
            SUc = Math.Round(SUc, 7);
            Console.WriteLine("suc : " + SUc);
        }

        public void ValidationOperate(int OpMode)
        {
            FillMatriks(OpMode);
            koefisienPartisi();
            entropyPartisi();
            fungsiValiditasKekompakanDanSeparasi();
        }
    }
}
